#include <cstdio>
#include <iostream>
#include <string>
#include <thread>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;

int g_val = 1000;

pthread_mutex_t mtx;

void* thread_run(void* name)
{
    while (true)
    {
        pthread_mutex_lock(&mtx);
        if (g_val > 0)
        {
            usleep(2000);
            cout << (const char*)name << " get a ticket, " << g_val-- << endl;
            pthread_mutex_unlock(&mtx);
        }
        else
        {
            cout << "no last tickets" << endl;
            pthread_mutex_unlock(&mtx);
            break;
        }
        usleep(100);
    }
    return nullptr;
}

/*
__thread int g_val = 0;

void* thread_run(void* args)
{
    pthread_detach(pthread_self());
    const char* name = static_cast<char*>(args);

    int cnt = 0;
    while (true)
    {
        cout << name << ", &cnt: " << &cnt << ", g_val: " << g_val++ << ", &g_val: " << &g_val << endl;
        sleep(1);
    }

    return args;
} 
*/

int main()
{
    pthread_mutex_init(&mtx, nullptr);

    pthread_t t[4];
    int n = sizeof(t) / sizeof(pthread_t);
    
    for (int i = 0; i < n; i++) 
    {
        char* data = new char[64];
        sprintf(data, "thread-%d", i);

        pthread_create(&t[i], nullptr, thread_run, (void*)data);
        pthread_detach(t[i]);
    }

    pthread_mutex_destroy(&mtx);

    // sleep(1);
    // assert(pthread_join(t1, nullptr) == 0);
    
    while(true)
    {
        sleep(1);
    }

    return 0;
}

// int main()
// {
//     pthread_t t;
//     pthread_create(&t, nullptr, thread_run, (void*)"thread 1");
// 
//     sleep(1);
//     pthread_cancel(t);
// 
//     void* ret = nullptr;
//     assert(pthread_join(t, &ret) == 0);
// 
//     // cout << "ret: " << (char*)ret << endl;
//     cout << "ret: " << (int64_t)ret << endl;
// 
//     return 0;
// }


// void run1()
// {
//     while (true)
//     {
//         cout << "run1" << endl;
//         sleep(1);
//     }
// }
// 
// void run2()
// {
//     while (true)
//     {
//         cout << "run2" << endl;
//         sleep(1);
//     }
// }
// 
// void run3()
// {
//     while (true)
//     {
//         cout << "run3" << endl;
//         sleep(1);
//     }
// }
// 
// int main()
// {
//     thread t1(run1);
//     thread t2(run2);
//     thread t3(run3);
// 
//     t1.join();
//     t2.join();
//     t3.join();
// 
//     return 0;
// }
